#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OCR API服务 - 提供身份证和银行卡识别接口
支持文件上传和URL识别
"""

from flask import Flask, request, jsonify
import os
import tempfile
import requests
from datetime import datetime
import re
import traceback
import logging
from logging.handlers import RotatingFileHandler
import time
import uuid
from functools import wraps
from src.id_card_reader import IDCardReader
from src.bank_card_reader import BankCardReader
from src.invoice_reader import InvoiceReader
from src.business_license_reader import BusinessLicenseReader, BusinessLicenseValidator
from src.business_license_errors import business_license_error_handler
from src.business_license_temp_file_manager import (
    safe_temp_file_from_upload, 
    safe_temp_file_from_url,
    global_temp_file_manager
)

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB

# 配置日志
if not os.path.exists('logs'):
    os.mkdir('logs')

# 设置应用日志
app_handler = RotatingFileHandler('logs/ocr_api.log', maxBytes=10240000, backupCount=10)
app_handler.setFormatter(logging.Formatter(
    '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
))
app_handler.setLevel(logging.INFO)
app.logger.addHandler(app_handler)
app.logger.setLevel(logging.INFO)

# 设置请求日志
request_logger = logging.getLogger('ocr_requests')
request_handler = RotatingFileHandler('logs/ocr_requests.log', maxBytes=10240000, backupCount=10)
request_handler.setFormatter(logging.Formatter(
    '%(asctime)s - %(message)s'
))
request_handler.setLevel(logging.INFO)
request_logger.addHandler(request_handler)
request_logger.setLevel(logging.INFO)

app.logger.info('OCR API启动')

def log_request_response(func):
    """请求和响应日志装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 生成请求ID
        request_id = str(uuid.uuid4())[:8]
        start_time = time.time()
        
        # 记录请求信息
        client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', 'unknown'))
        user_agent = request.headers.get('User-Agent', 'unknown')
        
        # 构建请求日志
        request_info = {
            'request_id': request_id,
            'method': request.method,
            'endpoint': request.endpoint,
            'url': request.url,
            'client_ip': client_ip,
            'user_agent': user_agent,
            'content_length': request.content_length or 0,
        }
        
        # 记录文件信息（如果有）
        if request.files:
            # 避免读取大文件进入内存，仅记录元信息
            files_info = []
            for key, file in request.files.items():
                if file.filename:
                    size = getattr(file, 'content_length', None)
                    files_info.append({
                        'field': key,
                        'filename': file.filename,
                        'size': size if size is not None else 'unknown'
                    })
            request_info['files'] = files_info
        
        # 记录JSON数据（如果有）
        if request.is_json and request.json:
            # 隐藏敏感信息，只记录结构
            json_data = dict(request.json)
            if 'url' in json_data:
                json_data['url'] = f"{json_data['url'][:50]}..." if len(json_data['url']) > 50 else json_data['url']
            request_info['json_data'] = json_data
        
        request_logger.info(f"REQUEST: {request_info}")
        
        try:
            # 执行原函数
            response = func(*args, **kwargs)
            
            # 计算处理时间
            processing_time = round(time.time() - start_time, 3)
            
            # 记录响应信息
            if hasattr(response, 'get_json') and response.get_json():
                response_data = response.get_json()
                
                # 构建响应日志（隐藏敏感信息）
                response_info = {
                    'request_id': request_id,
                    'status_code': response.status_code,
                    'success': response_data.get('success', False),
                    'processing_time': f"{processing_time}s",
                    'response_size': len(str(response_data))
                }
                
                # 记录识别结果统计（不记录具体内容）
                if 'data' in response_data and response_data['data']:
                    data = response_data['data']
                    result_stats = {}
                    
                    # 统计识别到的字段
                    for key, value in data.items():
                        if value and str(value).strip():
                            result_stats[f"{key}_recognized"] = True
                        else:
                            result_stats[f"{key}_recognized"] = False
                    
                    response_info['recognition_stats'] = result_stats
                
                # 记录验证结果
                if 'validation' in response_data:
                    validation = response_data['validation']
                    response_info['validation_result'] = validation.get('valid', False)
                
                # 记录错误信息
                if not response_data.get('success') and 'error' in response_data:
                    response_info['error_type'] = type(response_data['error']).__name__
                    response_info['error_message'] = str(response_data['error'])[:100]  # 限制错误消息长度
                
                request_logger.info(f"RESPONSE: {response_info}")
            
            return response
            
        except Exception as e:
            # 记录异常信息
            processing_time = round(time.time() - start_time, 3)
            error_info = {
                'request_id': request_id,
                'status_code': 500,
                'success': False,
                'processing_time': f"{processing_time}s",
                'error_type': type(e).__name__,
                'error_message': str(e)[:100],
                'traceback': traceback.format_exc()[-500:]  # 记录最后500字符的traceback
            }
            request_logger.error(f"ERROR: {error_info}")
            raise
    
    return wrapper

# 初始化识别器 - 启用快速模式
id_reader = IDCardReader(use_fast_mode=True, max_image_size=1280)
bank_reader = BankCardReader()
invoice_reader = InvoiceReader()
business_license_reader = BusinessLicenseReader(use_fast_mode=True, max_image_size=1920, logger=app.logger)

class DataValidator:
    """数据验证器"""
    
    @staticmethod
    def validate_id_number(id_number: str) -> dict:
        """验证身份证号码"""
        if not id_number or len(id_number) != 18:
            return {"valid": False, "error": "身份证号码长度不正确"}
        
        # 验证格式
        pattern = r'^[1-8]\d{5}(19[0-9]\d|20[0-4]\d|2050)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$'
        if not re.match(pattern, id_number):
            return {"valid": False, "error": "身份证号码格式不正确"}
        
        # 提取日期部分
        birth_str = id_number[6:14]
        year = int(birth_str[:4])
        month = int(birth_str[4:6])
        day = int(birth_str[6:8])
        
        # 验证日期合理性
        try:
            datetime(year, month, day)
        except ValueError:
            return {"valid": False, "error": "身份证号码中的日期不合理"}
        
        # 校验码验证
        weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        check_codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
        
        sum_val = sum(int(id_number[i]) * weights[i] for i in range(17))
        check_code = check_codes[sum_val % 11]
        
        if id_number[17].upper() != check_code:
            return {"valid": False, "error": "身份证校验码不正确"}
        
        return {
            "valid": True,
            "birth_date": f"{year}-{month:02d}-{day:02d}",
            "age": datetime.now().year - year
        }
    
    @staticmethod
    def validate_bank_card_number(card_number: str) -> dict:
        """验证银行卡号（Luhn算法）"""
        if not card_number or not card_number.isdigit():
            return {"valid": False, "error": "银行卡号格式不正确"}
        # 常见长度：国内银行卡多为16或19位；也兼容15位（如AmEx）
        if not (15 <= len(card_number) <= 19):
            return {"valid": False, "error": "银行卡号长度不正确"}
        
        # Luhn算法验证
        total = 0
        reverse_digits = card_number[::-1]
        
        for i, digit in enumerate(reverse_digits):
            n = int(digit)
            if i % 2 == 1:
                n *= 2
                if n > 9:
                    n = n // 10 + n % 10
            total += n
        
        if total % 10 != 0:
            return {"valid": False, "error": "银行卡号校验失败"}
        
        return {"valid": True}
    
    @staticmethod
    def validate_valid_date(date_str: str) -> dict:
        """验证身份证有效期"""
        if not date_str:
            return {"valid": False, "error": "有效期为空"}
        
        if "长期" in date_str:
            return {"valid": True, "type": "permanent"}
        
        # 匹配YYYY.MM.DD-YYYY.MM.DD或YYYY.MM.DD - YYYY.MM.DD格式
        pattern = r'(\d{4})\.(\d{2})\.(\d{2})\s*-\s*(\d{4})\.(\d{2})\.(\d{2})'
        match = re.search(pattern, date_str)
        
        if not match:
            return {"valid": False, "error": "有效期格式不正确"}
        
        start_year, start_month, start_day, end_year, end_month, end_day = map(int, match.groups())
        
        try:
            start_date = datetime(start_year, start_month, start_day)
            end_date = datetime(end_year, end_month, end_day)
            
            if end_date <= start_date:
                return {"valid": False, "error": "有效期结束日期不能早于开始日期"}
            
            now = datetime.now()
            is_expired = now > end_date
            
            return {
                "valid": True,
                "start_date": start_date.strftime("%Y-%m-%d"),
                "end_date": end_date.strftime("%Y-%m-%d"),
                "is_expired": is_expired
            }
            
        except ValueError:
            return {"valid": False, "error": "有效期日期不合理"}

def download_image(url: str) -> str:
    """下载远程文件到临时文件，自动识别图片或PDF。

    注意：仅允许 http/https；限制最大下载 16MB；根据 Content-Type/URL 决定后缀。
    """
    try:
        # 协议白名单
        if not (url.lower().startswith('http://') or url.lower().startswith('https://')):
            raise ValueError('只支持 http/https 协议')

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        # 流式下载并限制大小
        resp = requests.get(url, headers=headers, timeout=30, stream=True)
        resp.raise_for_status()

        content_type = resp.headers.get('Content-Type', '').lower()
        # 依据 Content-Type 或 URL 后缀判断
        is_pdf = ('pdf' in content_type) or url.lower().endswith('.pdf')
        # 常见图片类型
        is_image = ('image/' in content_type) or url.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.webp'))

        suffix = '.pdf' if is_pdf else '.jpg'
        # 最大 16MB，与 Flask MAX_CONTENT_LENGTH 保持一致
        max_bytes = 16 * 1024 * 1024
        downloaded = 0

        tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
        try:
            for chunk in resp.iter_content(chunk_size=8192):
                if not chunk:
                    continue
                downloaded += len(chunk)
                if downloaded > max_bytes:
                    raise ValueError('文件过大，超过16MB限制')
                tmp.write(chunk)
        finally:
            tmp.close()

        # 简单类型校验（非强校验）：若非 PDF 也非图片，给出警告型错误
        if not (is_pdf or is_image):
            app.logger.warning(f"未知的Content-Type: {content_type}，按 {suffix} 处理")

        return tmp.name
    except Exception as e:
        raise Exception(f"下载文件失败: {str(e)}")

def save_uploaded_file(file) -> str:
    """保存上传的文件，确保关闭临时文件句柄。"""
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.jpg')
    try:
        file.save(temp_file.name)
    finally:
        temp_file.close()
    return temp_file.name

def cleanup_temp_file(file_path: str):
    """清理临时文件"""
    try:
        if os.path.exists(file_path):
            os.unlink(file_path)
    except:
        pass

def validate_file_format(filename: str) -> bool:
    """验证文件格式是否支持
    
    Args:
        filename: 文件名
        
    Returns:
        bool: 是否支持的格式
    """
    if not filename:
        return False
    
    # 支持的图片格式
    supported_formats = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif', '.webp'}
    
    # 获取文件扩展名并转换为小写
    file_ext = os.path.splitext(filename.lower())[1]
    
    return file_ext in supported_formats

def validate_file_size(file) -> bool:
    """验证文件大小是否在限制范围内
    
    Args:
        file: Flask文件对象
        
    Returns:
        bool: 文件大小是否合规
    """
    # Flask的MAX_CONTENT_LENGTH已经设置为16MB
    # 这里可以添加额外的验证逻辑
    return True

@app.route('/api/id_card/front/upload', methods=['POST'])
@log_request_response
def id_card_front_upload():
    """接口1: 上传图片识别身份证正面"""
    temp_file = None
    try:
        if 'file' not in request.files:
            return jsonify({"success": False, "error": "未找到上传文件"}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({"success": False, "error": "未选择文件"}), 400
        
        temp_file = save_uploaded_file(file)
        result = id_reader.read_id_card_front(temp_file)
        
        # 验证识别结果
        if not result.id_number and not result.name:
            return jsonify({"success": False, "error": "未识别到身份证信息，请确保图片清晰且包含身份证正面"}), 400
        
        # 数据验证
        validation = {}
        if result.id_number:
            validation = DataValidator.validate_id_number(result.id_number)
        
        response = {
            "success": True,
            "data": {
                "name": result.name,
                "gender": result.gender,
                "ethnicity": result.nationality,
                "birth_date": result.birth_date,
                "address": result.address,
                "id_number": result.id_number
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/id_card/front/url', methods=['POST'])
@log_request_response
def id_card_front_url():
    """接口2: 通过URL识别身份证正面"""
    temp_file = None
    try:
        data = request.get_json()
        if not data or 'url' not in data:
            return jsonify({"success": False, "error": "未提供图片URL"}), 400
        
        temp_file = download_image(data['url'])
        result = id_reader.read_id_card_front(temp_file)
        
        # 验证识别结果
        if not result.id_number and not result.name:
            return jsonify({"success": False, "error": "未识别到身份证信息，请确保图片清晰且包含身份证正面"}), 400
        
        # 数据验证
        validation = {}
        if result.id_number:
            validation = DataValidator.validate_id_number(result.id_number)
        
        response = {
            "success": True,
            "data": {
                "name": result.name,
                "gender": result.gender,
                "ethnicity": result.nationality,
                "birth_date": result.birth_date,
                "address": result.address,
                "id_number": result.id_number
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/id_card/back/upload', methods=['POST'])
@log_request_response
def id_card_back_upload():
    """接口3: 上传图片识别身份证反面"""
    temp_file = None
    try:
        if 'file' not in request.files:
            return jsonify({"success": False, "error": "未找到上传文件"}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({"success": False, "error": "未选择文件"}), 400
        
        temp_file = save_uploaded_file(file)
        result = id_reader.read_id_card_back(temp_file)
        
        # 验证识别结果
        if not result.valid_period and not result.issuing_authority:
            return jsonify({"success": False, "error": "未识别到身份证信息，请确保图片清晰且包含身份证反面"}), 400
        
        # 数据验证
        validation = {}
        if result.valid_period:
            validation = DataValidator.validate_valid_date(result.valid_period)
        
        response = {
            "success": True,
            "data": {
                "issuing_authority": result.issuing_authority,
                "valid_date": result.valid_period
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/id_card/back/url', methods=['POST'])
@log_request_response
def id_card_back_url():
    """接口4: 通过URL识别身份证反面"""
    temp_file = None
    try:
        data = request.get_json()
        if not data or 'url' not in data:
            return jsonify({"success": False, "error": "未提供图片URL"}), 400
        
        temp_file = download_image(data['url'])
        result = id_reader.read_id_card_back(temp_file)
        
        # 验证识别结果
        if not result.valid_period and not result.issuing_authority:
            return jsonify({"success": False, "error": "未识别到身份证信息，请确保图片清晰且包含身份证反面"}), 400
        
        # 数据验证
        validation = {}
        if result.valid_period:
            validation = DataValidator.validate_valid_date(result.valid_period)
        
        response = {
            "success": True,
            "data": {
                "issuing_authority": result.issuing_authority,
                "valid_date": result.valid_period
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/bank_card/upload', methods=['POST'])
@log_request_response
def bank_card_upload():
    """接口5: 上传图片识别银行卡"""
    temp_file = None
    try:
        if 'file' not in request.files:
            return jsonify({"success": False, "error": "未找到上传文件"}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({"success": False, "error": "未选择文件"}), 400
        
        temp_file = save_uploaded_file(file)
        result = bank_reader.read_bank_card(temp_file)
        
        # 验证识别结果
        if not result.card_number and not result.bank_name:
            return jsonify({"success": False, "error": "未识别到银行卡信息，请确保图片清晰且包含银行卡"}), 400
        
        # 数据验证
        validation = {}
        if result.card_number:
            validation = DataValidator.validate_bank_card_number(result.card_number)
        
        response = {
            "success": True,
            "data": {
                "card_number": result.card_number,
                "bank_name": result.bank_name,
                "card_type": result.card_type,
                "holder_name": result.holder_name,
                "valid_date": result.valid_date
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/bank_card/url', methods=['POST'])
@log_request_response
def bank_card_url():
    """接口6: 通过URL识别银行卡"""
    temp_file = None
    try:
        data = request.get_json()
        if not data or 'url' not in data:
            return jsonify({"success": False, "error": "未提供图片URL"}), 400
        
        temp_file = download_image(data['url'])
        result = bank_reader.read_bank_card(temp_file)
        
        # 验证识别结果
        if not result.card_number and not result.bank_name:
            return jsonify({"success": False, "error": "未识别到银行卡信息，请确保图片清晰且包含银行卡"}), 400
        
        # 数据验证
        validation = {}
        if result.card_number:
            validation = DataValidator.validate_bank_card_number(result.card_number)
        
        response = {
            "success": True,
            "data": {
                "card_number": result.card_number,
                "bank_name": result.bank_name,
                "card_type": result.card_type,
                "holder_name": result.holder_name,
                "valid_date": result.valid_date
            },
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/invoice/upload', methods=['POST'])
@log_request_response
def invoice_upload():
    """接口7: 上传PDF或图片识别发票"""
    temp_file = None
    try:
        if 'file' not in request.files:
            return jsonify({"success": False, "error": "未找到上传文件"}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({"success": False, "error": "未选择文件"}), 400
        
        # 保存上传的文件
        temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf' if file.filename.lower().endswith('.pdf') else '.jpg')
        try:
            file.save(temp_file.name)
        finally:
            temp_file.close()
        
        result = invoice_reader.read_invoice(temp_file.name)
        
        # 验证识别结果
        if not result.invoice_number and not result.seller_name and not result.total_amount:
            return jsonify({"success": False, "error": "未识别到发票信息，请确保文件清晰且包含发票内容"}), 400
        
        # 数据验证
        validation = invoice_reader.validate_invoice_info(result)
        
        response = {
            "success": True,
            "data": result.to_dict(),
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file.name)

@app.route('/api/invoice/url', methods=['POST'])
@log_request_response
def invoice_url():
    """接口8: 通过URL识别发票PDF或图片"""
    temp_file = None
    try:
        data = request.get_json()
        if not data or 'url' not in data:
            return jsonify({"success": False, "error": "未提供文件URL"}), 400
        
        # 支持图片或PDF的远程下载
        temp_file = download_image(data['url'])
        result = invoice_reader.read_invoice(temp_file)
        
        # 验证识别结果
        if not result.invoice_number and not result.seller_name and not result.total_amount:
            return jsonify({"success": False, "error": "未识别到发票信息，请确保文件清晰且包含发票内容"}), 400
        
        # 数据验证
        validation = invoice_reader.validate_invoice_info(result)
        
        response = {
            "success": True,
            "data": result.to_dict(),
            "validation": validation
        }
        
        return jsonify(response)
        
    except Exception as e:
        return jsonify({"success": False, "error": str(e)}), 500
    finally:
        if temp_file:
            cleanup_temp_file(temp_file)

@app.route('/api/business_license/upload', methods=['POST'])
@log_request_response
def business_license_upload():
    """接口9: 上传营业执照图片进行识别"""
    try:
        # 检查是否有上传文件
        if 'file' not in request.files:
            return jsonify({
                "success": False, 
                "error": "未找到上传文件，请确保使用'file'字段上传文件",
                "error_type": "file_not_found"
            }), 400
        
        file = request.files['file']
        
        # 检查文件名是否为空
        if file.filename == '':
            return jsonify({
                "success": False, 
                "error": "未选择文件，请选择营业执照图片文件",
                "error_type": "file_empty"
            }), 400
        
        # 验证文件格式
        if not validate_file_format(file.filename):
            return jsonify({
                "success": False, 
                "error": "不支持的文件格式，请上传JPG、PNG、BMP、TIFF或WEBP格式的图片",
                "error_type": "file_format_unsupported"
            }), 400
        
        # 使用安全的临时文件管理器
        with safe_temp_file_from_upload(file, manager=global_temp_file_manager) as temp_file:
            # 使用营业执照读取器进行识别
            result = business_license_reader.read_business_license(temp_file)
            
            # 数据验证
            validation = BusinessLicenseValidator.validate_business_license_info(result)
            
            # 构建响应数据
            response = {
                "success": True,
                "data": result.to_dict(),
                "validation": validation
            }
            
            return jsonify(response)
        
    except Exception as e:
        # 使用统一错误处理器
        error_response = business_license_error_handler.handle_error(
            e, 
            context={
                'endpoint': 'business_license_upload',
                'filename': getattr(request.files.get('file'), 'filename', 'unknown') if 'file' in request.files else None,
                'debug_mode': app.debug
            }
        )
        
        # 根据错误类型返回适当的HTTP状态码
        if 'file_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'network_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'validation_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'recognition_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'ocr_' in error_response.get('error_type', ''):
            status_code = 500
        elif 'system_' in error_response.get('error_type', ''):
            status_code = 500
        else:
            status_code = 500
        
        return jsonify(error_response), status_code


@app.route('/api/business_license/url', methods=['POST'])
@log_request_response
def business_license_url():
    """接口10: 通过URL识别营业执照"""
    try:
        # 检查请求数据
        data = request.get_json()
        if not data or 'url' not in data:
            return jsonify({
                "success": False, 
                "error": "未提供图片URL，请在请求体中包含'url'字段",
                "error_type": "network_url_invalid"
            }), 400
        
        url = data['url'].strip()
        if not url:
            return jsonify({
                "success": False, 
                "error": "URL不能为空",
                "error_type": "network_url_invalid"
            }), 400
        
        # 使用安全的临时文件管理器从URL下载
        with safe_temp_file_from_url(url, manager=global_temp_file_manager) as temp_file:
            # 使用营业执照读取器进行识别
            result = business_license_reader.read_business_license(temp_file)
            
            # 数据验证
            validation = BusinessLicenseValidator.validate_business_license_info(result)
            
            # 构建响应数据
            response = {
                "success": True,
                "data": result.to_dict(),
                "validation": validation
            }
            
            return jsonify(response)
        
    except Exception as e:
        # 使用统一错误处理器
        error_response = business_license_error_handler.handle_error(
            e, 
            context={
                'endpoint': 'business_license_url',
                'url': data.get('url') if 'data' in locals() and data else None,
                'debug_mode': app.debug
            }
        )
        
        # 根据错误类型返回适当的HTTP状态码
        if 'file_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'network_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'validation_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'recognition_' in error_response.get('error_type', ''):
            status_code = 400
        elif 'ocr_' in error_response.get('error_type', ''):
            status_code = 500
        elif 'system_' in error_response.get('error_type', ''):
            status_code = 500
        else:
            status_code = 500
        
        return jsonify(error_response), status_code


@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查接口"""
    # stats = performance_monitor_instance.get_stats()
    # memory_mb = MemoryOptimizer.get_memory_usage()
    
    # 获取临时文件管理器状态
    temp_files_count = global_temp_file_manager.get_temp_files_count()
    
    # 检查错误处理系统状态
    error_handler_status = "operational"
    try:
        # 测试错误处理器是否正常工作
        test_error = BusinessLicenseFileError(
            BusinessLicenseErrorType.FILE_NOT_FOUND,
            "健康检查测试错误",
            {}
        )
        test_result = business_license_error_handler.handle_error(test_error, {"health_check": True})
        if not test_result or test_result.get("success", True):
            error_handler_status = "degraded"
    except Exception:
        error_handler_status = "failed"
    
    return jsonify({
        "success": True,
        "service": "OCR API - Enhanced Version with Error Handling",
        "status": "running",
        "performance": {
            "total_requests": 0,
            "success_rate": 100.0,
            "avg_response_time": 0.0,
            "current_memory_mb": 0.0,
            "peak_memory_mb": 0.0
        },
        "error_handling": {
            "status": error_handler_status,
            "temp_files_count": temp_files_count,
            "supported_error_types": [
                "file_errors",
                "network_errors", 
                "ocr_errors",
                "recognition_errors",
                "validation_errors",
                "system_errors"
            ]
        },
        "endpoints": [
            "POST /api/id_card/front/upload - 上传身份证正面",
            "POST /api/id_card/front/url - URL身份证正面",
            "POST /api/id_card/back/upload - 上传身份证反面", 
            "POST /api/id_card/back/url - URL身份证反面",
            "POST /api/bank_card/upload - 上传银行卡",
            "POST /api/bank_card/url - URL银行卡",
            "POST /api/invoice/upload - 上传发票PDF/图片",
            "POST /api/invoice/url - URL发票PDF/图片",
            "POST /api/business_license/upload - 上传营业执照图片（支持错误处理）",
            "POST /api/business_license/url - URL营业执照图片（支持错误处理）",
            "GET /api/performance - 性能统计",
            "GET /api/health - 健康检查（包含错误处理状态）"
        ]
    })

@app.route('/api/performance', methods=['GET'])
def get_performance_stats():
    """获取性能统计"""
    return jsonify({
        "success": True,
        "stats": {},
        "system": {
            "cpu_percent": 0,
            "memory_percent": 0,
            "available_memory_mb": 0
        }
    })

@app.errorhandler(413)
def file_too_large(error):
    return jsonify({"success": False, "error": "文件太大，最大支持16MB"}), 413

if __name__ == '__main__':
    print("🚀 OCR API服务启动中...")
    print("📋 可用接口:")
    print("  1. POST /api/id_card/front/upload - 上传身份证正面")
    print("  2. POST /api/id_card/front/url - URL身份证正面") 
    print("  3. POST /api/id_card/back/upload - 上传身份证反面")
    print("  4. POST /api/id_card/back/url - URL身份证反面")
    print("  5. POST /api/bank_card/upload - 上传银行卡")
    print("  6. POST /api/bank_card/url - URL银行卡")
    print("  7. POST /api/invoice/upload - 上传发票PDF/图片")
    print("  8. POST /api/invoice/url - URL发票PDF/图片")
    print("  9. POST /api/business_license/upload - 上传营业执照图片")
    print("  10. POST /api/business_license/url - URL营业执照图片")
    print("  ✅ GET /api/health - 健康检查")
    
    app.run(host='0.0.0.0', port=5000, debug=False)
